package main

import (
	"fmt"
	"unsafe"
)

func main() {
	//s1 s2  s2 := s1
	//var s1 []int{1,2,3,4}
	//s2 :=s1
	//引用类型 值类型
	//深拷贝 和 浅拷贝
	s1 := "dk"
	s2 := s1
	fmt.Println("s1和s2", s1, s2)
	s2 = "dot"
	fmt.Println("s1和s2", s1, s2)
	slice1 := []int{1, 2, 3, 4, 5}
	slice2 := slice1 //浅拷贝
	fmt.Println("slice1:", slice1)
	fmt.Println("slice2:", slice2)

	slice2[1] = 88 //1 88 3 4 5
	fmt.Println("修改后的slice1:", slice1)
	fmt.Println("修改后的slice2:", slice2)
	//值类型: 复制变量的时候是深拷贝，值类型包括： int 、float、string、struct、array、bool

	//引用类型：复制变量的时候是浅拷贝，引用类型包括slice、map、channel、interface

	//深拷贝：复制一个变量时，会创建一个全新的变量，并且将原始数据复制给新变量，
	// 新变量在内存中会是一个新的地址，并且两个变量修改不会影响其他变量

	//浅拷贝：复制一个变量时，也会创建一个新的变量，但是两个变量共享底层的数据，
	// 也就是新旧变量会指向同一个数据的内存地址，实际上算是引用同一个数据，
	// 也就意味着任意一个变量发生变更，其他变量也会被修改
	// var slice3 = []int{1, 2, 3, 4, 5, 6}
	slice3 := make([]int, 5, 10)

	//浅拷贝
	copy(slice3, slice1)
	fmt.Println(slice3)
	slice3[1] = 99
	fmt.Println(slice3)
	fmt.Println(slice1)

	//打印某个值的内存地址
	fmt.Println("slice1的内存地址", unsafe.Pointer(&slice1))
	fmt.Println("slice3的内存地址", unsafe.Pointer(&slice3))
	fmt.Println("slice1的元素第一个内存地址", unsafe.Pointer(&slice1[0]))
	fmt.Println("slice3的元素第一个内存地址", unsafe.Pointer(&slice3[0]))

}
